#include "app_buffer.h"



sub_buffer_t *app_buffer_init_sub_buffer(int capacity)
{
    sub_buffer_t *sub_buffer = (sub_buffer_t *)malloc(sizeof(sub_buffer_t));
    if (sub_buffer == NULL)
    {
        perror("malloc sub_buffer failed");
        return NULL;
    }
    sub_buffer->capacity = capacity;
    sub_buffer->len = 0;
    sub_buffer->ptr = (uint8_t *)malloc(capacity);
    memset(sub_buffer->ptr, 0, capacity);
    return sub_buffer;
}

buffer_t *app_buffer_init(int capacity)
{
    // 申请缓冲区结构体内存
    buffer_t *buffer = (buffer_t *)malloc(sizeof(buffer_t));
    if (buffer == NULL)
    {
        perror("malloc buffer failed");
        return NULL;
    }

    buffer->sub_buffers[0] = app_buffer_init_sub_buffer(capacity);
    if (buffer->sub_buffers[0] == NULL)
    {
        log_error("app_buffer_init_sub_buffer failed");
        return NULL;
    }

    buffer->sub_buffers[1] = app_buffer_init_sub_buffer(capacity);
    if (buffer->sub_buffers[1] == NULL)
    {
        log_error("app_buffer_init_sub_buffer failed");
        return NULL;
    }

    buffer->read_index = 0;  // 默认第0个子缓冲区用来读
    buffer->write_index = 1; // 默认第1个子缓冲区用来写

    pthread_mutex_init(&buffer->r_mutext, NULL); // 初始化读锁
    pthread_mutex_init(&buffer->w_mutext, NULL); // 初始化写锁

    return buffer;
}

void app_buffer_deInit(buffer_t *buffer)
{
    free(buffer->sub_buffers[0]->ptr);
    free(buffer->sub_buffers[0]);
    free(buffer->sub_buffers[1]->ptr);
    free(buffer->sub_buffers[1]);

    pthread_mutex_destroy(&buffer->r_mutext);
    pthread_mutex_destroy(&buffer->w_mutext);

    free(buffer);
}

/**
 * @brief 写数据
 *
 * @param buffer 缓冲区
 * @param data 数据
 * @param len 数据长度
 * @return gate_status_t 成功返回OK 失败返回ERRROR
 */
gate_status_t app_buffer_write(buffer_t *buffer, uint8_t *data, uint8_t len)
{

    // 获取写锁
    pthread_mutex_lock(&buffer->w_mutext);
    // 1. 找到要写的缓冲区
    sub_buffer_t *sub_buffer = buffer->sub_buffers[buffer->write_index];
    if (sub_buffer->capacity - sub_buffer->len < len + 1)
    {
        log_warn("缓冲区剩余空间不足: 剩余空间: %d, 需要空间: %d",
                 sub_buffer->capacity - sub_buffer->len,
                 len + 1);
        pthread_mutex_unlock(&buffer->w_mutext);
        return ERROR;
    }

    // 开始写缓冲区: 先写长度, 再写真实数据
    sub_buffer->ptr[sub_buffer->len] = len;
    memcpy(sub_buffer->ptr + sub_buffer->len + 1, data, len);

    sub_buffer->len += len + 1;

    pthread_mutex_unlock(&buffer->w_mutext);
    log_debug("写入缓冲区成功");
    return OK;
}

/**
 * @brief 读取缓冲区数据
 *
 * @param buffer 缓冲区指针
 * @param data 读取到的数据
 * @param data_capacity 能够读取的数据最大长度
 * @return uint8_t 读取到的数据实际长度
 */
uint8_t app_buffer_read(buffer_t *buffer, uint8_t *data, int data_capacity)
{
    pthread_mutex_lock(&buffer->r_mutext);

    sub_buffer_t *sub_buffer = buffer->sub_buffers[buffer->read_index];

    // 判断缓冲区是否有数据
    if (sub_buffer->len == 0)
    {
        // 交换缓冲区
        // 要交换的缓冲区加写锁
        //log_debug("缓冲区交换");
        pthread_mutex_lock(&buffer->w_mutext);
        int tmp = buffer->read_index;
        buffer->read_index = buffer->write_index;
        buffer->write_index = tmp;
        pthread_mutex_unlock(&buffer->w_mutext);

        sub_buffer = buffer->sub_buffers[buffer->read_index];
        if (sub_buffer->len == 0)
        {
            //log_warn("缓冲区为空, 读数据失败");
            pthread_mutex_unlock(&buffer->r_mutext);
            return 0;
        }
    }

    // 缓冲区非空, 有数据
    uint8_t r_value = sub_buffer->ptr[0];
    if (data_capacity < r_value)
    {
        log_warn("数据长度超出缓冲区容量");
        pthread_mutex_unlock(&buffer->r_mutext);
        return 0;
    }

    // copy真正的数据
    memcpy(data, sub_buffer->ptr + 1, r_value);

    // 后面的数据前移
    memmove(sub_buffer->ptr, sub_buffer->ptr + r_value + 1, sub_buffer->len - r_value - 1);
    
    // 更新剩下的字节数
    sub_buffer->len -= r_value + 1;

    pthread_mutex_unlock(&buffer->r_mutext);

    return r_value;
}
